﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Windows.Admin.Domain;
using Windows.Admin.Infrastructure.EFCore;
using Windows.Admin.Infrastructure.EFCore.Extensions;
using Windows.Application.Share;
using Windows.Infrastructure.Share.Extensions;
using Windows.Infrastructure.Share.Security;
using Windows.SeedWord;

namespace Windows.Admin.Application
{
    public class AppService : IAppService
    {
        private readonly IMapper _mapper;
        private readonly AdminDbContext _db;
        private readonly ICurrentUser _currentUser;
        public AppService(IMapper mapper, AdminDbContext db, ICurrentUser currentUser)
        {
            _mapper = mapper;
            _db = db;
            _currentUser = currentUser;
        }
        /// <summary>
        /// 获取应用列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<AppTreeResponse>> GetApps()
        {
            List<App> apps = await _db.App.ToListAsync();
            List<AppTreeResponse> list = BuildAppTree(apps);
            return list;
        }
        /// <summary>
        /// 获取ids的应用列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<AppTreeResponse>> GetNoResourceAppsByIds(List<long> ids)
        {
            List<App> apps = await _db.App.Where(x => ids.Contains(x.Id) && x.Type != (int)AppTypeEnum.Resource).ToListAsync();
            List<AppTreeResponse> list = BuildAppTree(apps);
            return list;
        }
        /// <summary>
        /// 获取当前用户的桌面快捷方式列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<AppResponse>> GetCurrentUserShortuts()
        {
            var apps = await _db.Shortcut.Include(x => x.App).Where(x => x.UserId == _currentUser.Id).Select(s => s.App).ToListAsync();
            var appDtos = _mapper.Map<List<AppResponse>>(apps);
            return appDtos;
        }
        /// <summary>
        /// 获取显示在角落的应用列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<AppResponse>> GetCornerApps()
        {
            List<App> apps = await _db.App.Where(x => x.ShowCorner).ToListAsync();
            var appDtos = _mapper.Map<List<AppResponse>>(apps);
            return appDtos;
        }
        /// <summary>
        /// 获取所有目录
        /// </summary>
        /// <returns></returns>
        public async Task<List<AppTreeResponse>> GetCatalogs()
        {
            List<App> catalogs = await _db.App.Where(x => x.Type == (int)AppTypeEnum.Catalog).ToListAsync();
            List<AppTreeResponse> list = BuildAppTree(catalogs);
            return list;
        }
        /// <summary>
        /// 获取不是资源类型的应用列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<AppTreeResponse>> GetNoResourceApps()
        {
            List<App> apps = await _db.App.Where(x => x.Type != (int)AppTypeEnum.Resource).ToListAsync();
            List<AppTreeResponse> list = BuildAppTree(apps);
            return list;
        }
        /// <summary>
        /// 获取pId的应用列表
        /// </summary>
        /// <param name="pId"></param>
        /// <returns></returns>
        public async Task<List<AppResponse>> GetByPId(int pId)
        {
            List<App>? apps = await _db.App.Where(x => x.Type == (int)AppTypeEnum.App).Where(x => x.PId == pId).OrderBy(o => o.Sort).ToListAsync();
            return _mapper.Map<List<AppResponse>>(apps);
        }
        /// <summary>
        /// 应用管理窗体
        /// </summary>
        /// <returns></returns>
        public async Task<List<AppTreeResponse>> Query()
        {
            List<App> apps = await _db.App.ToListAsync();
            List<AppTreeResponse> list = BuildAppTree(apps);
            return list;
        }
        /// <summary>
        /// 获取id的应用详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<AppResponse> Detail(int id)
        {
            var model = await _db.App.FindByIdAsync(id);
            return _mapper.Map<AppResponse>(model);
        }
        /// <summary>
        /// 应用保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task Save(AppSaveRequest request)
        {
            if (await _db.App.AnyAsync(x => x.Name.ToLower() == request.Name && x.Id != request.Id && x.PId == request.PId))
                throw new ApiException("名称已存在!");
            if (request.Id == null)
            {
                App model = _mapper.Map<App>(request);
                await _db.App.AddAsync(model);
            }
            else
            {
                App? model = await _db.App.FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("应用不存在!");
                model.PId = request.PId;
                model.Type = request.Type;
                model.Name = request.Name;
                model.Component = request.Component;
                model.License = request.License;
                model.Icon = request.Icon;
                model.ShowCorner = request.ShowCorner;
                model.Width = request.Width;
                model.Height = request.Height;
                model.Sort = request.Sort;
                model.Remark = request.Remark;
            }
            await _db.SaveChangesAsync();
        }
        protected List<AppTreeResponse> BuildAppTree(List<App>? apps, long? pId = null)
        {
            List<AppTreeResponse> list = (from d in apps
                                          where d.PId == pId
                                          orderby d.Sort
                                          select d into x
                                          select new AppTreeResponse
                                          {
                                              Id = x.Id,
                                              PId = x.PId,
                                              Type = x.Type,
                                              Name = x.Name,
                                              Component = x.Component,
                                              License = x.License,
                                              Icon = x.Icon,
                                              Width = x.Width,
                                              Height = x.Height,
                                              ShowCorner = x.ShowCorner,
                                              Sort = x.Sort,
                                              Remark = x.Remark,
                                              CreatedBy = x.CreatedBy,
                                              CreatedByName = x.CreatedByName,
                                              CreatedOn = x.CreatedOn,
                                              UpdatedBy = x.UpdatedBy,
                                              UpdatedByName = x.UpdatedByName,
                                              UpdatedOn = x.UpdatedOn,
                                              Children = BuildAppTree(apps, x.Id),
                                          }).ToList();
            return list;
        }
    }
}
